<template>
  <div class="app-warp">
    <BaseSearch
      v-if="searchConfig && searchConfig.length"
      ref="search"
      :config="searchConfig"
      :init-value="initValue"
      :reset="reset"
      :label-width="labelWidth"
      @onSearch="(data) => handleParamsChange(data, 'searchData')"
    />

    <slot />
    <BaseTable
      ref="table"
      v-bind="$attrs"
      border
      :data="souceData"
      :get-souce-data="resetTableData"
      :selectable="selectable"
      :refresh-btn="refreshBtn"
      :show-header="showHeader"
      v-on="$listeners"
    />
    <div v-if="showPagination" class="app-template-page__footer">
      <el-pagination
        :current-page="pageNo"
        :page-sizes="[10, 20, 30, 50, 100, 200, 500, 1000]"
        :page-size="pageSize"
        :layout="pageLayout"
        background
        :total="total"
        :pager-count="5"
        @size-change="(data) => handleParamsChange(data, 'pageSize')"
        @current-change="(data) => handleParamsChange(data, 'pageNo')"
      />
    </div>
  </div>
</template>

<script>
import BaseTable from "@/components/BaseTable"
import BaseSearch from "@/components/BaseSearch"

export default {
  name: "AppTemplatePage",
  components: {
    BaseTable,
    BaseSearch
  },

  props: {
    pageLayout: {
      type: String,
      default: "total, sizes, prev, pager, next, jumper"
    },
    initValue: {
      type: Object,
      default: () => {}
    },
    searchConfig: {
      type: Array,
      default: () => []
    },
    tableData: {
      type: Array,
      default: () => []
    },

    showHeader: {
      type: Boolean,
      default: true
    },
    showPagination: {
      type: Boolean,
      default: true
    },
    request: {
      type: Function,
      // required: true,
      default: () => null
    },
    selectable: {
      type: Function
    },

    handleParams: {
      type: Function,
      default: (params) => params
    },
    handleSourceData: {
      type: Function,
      default: (res) => {
        return res.data.list || res.data || []
      }
    },
    handleTotal: {
      type: Function,
      default: (res) => {
        const { headers = {} } = res
        return headers["x-total-count"] ? Number(headers["x-total-count"]) : 0
      }
    },
    immediate: {
      type: Boolean,
      default: true
    },
    otherParams: {
      type: Object,
      default: () => {}
    },
    labelWidth: {
      type: String,
      default: () => null
    },

    refresh: {
      type: Number,
      default: 0
    },
    refreshBtn: {
      type: Boolean,
      default: false
    }
  },

  data() {
    return {
      pageNo: 1,
      pageSize: 10,
      total: 0,
      searchData: {},
      souceData: [],

      searchParams: {},
      reset: false
    }
  },
  watch: {
    refresh: {
      immediate: true,
      handler(val) {
        if (val) this.getSouceData(this.initValue)
      }
    },
    otherParams: {
      deep: true,
      handler() {
        this.getSouceData()
      }
    },
    tableData: {
      deep: true,
      immediate: true,
      handler(val) {
        this.souceData = [...val]
      }
    }
  },
  created() {
    this.immediate && this.getSouceData(this.initValue)
  },

  methods: {
    clearSelection() {
      this.$refs.table && this.$refs.table.clearSelection()
    },
    search() {
      this.$refs.search.refresh()
    },

    handleParamsChange(data, key) {
      this[key] = data

      if (["searchData"].includes(key)) {
        this.pageNo = 1
      }

      let tempObj = {}
      if (key === "searchData" && this.initValue) {
        tempObj = { ...this.initValue }
        Object.keys(this.initValue).forEach((k) => {
          tempObj[k] = data[k] || ""
        })
      }
      this.getSouceData(tempObj, true)
    },
    getParams(initValue = {}) {
      const { pageNo, pageSize, searchData, otherParams } = this

      const params = {
        pageNo: pageNo,
        pageSize,
        ...searchData,
        ...otherParams,
        ...initValue
      }
      let bool = params.searchRangeTime && Array.isArray(params.searchRangeTime)
      if (bool) {
        params.startTime = this.$fn.parseDateStr(params.searchRangeTime[0])
        params.endTime = this.$fn.parseDateStr(params.searchRangeTime[1])
        delete params.searchRangeTime
      }
      let bool1 =
        params.searchRangeTime1 && Array.isArray(params.searchRangeTime1)
      if (bool1) {
        params.beginDate = this.$fn.parseDateStr(params.searchRangeTime1[0])
        params.endDate = this.$fn.parseDateStr(params.searchRangeTime1[1])
        delete params.searchRangeTime1
      }
      let bool2 = params.signUpState === ""
      if (bool2) {
        params.signUpState = 3
      }
      return params
    },
    async getSouceData(initValue = {}) {
      let params = this.getParams(initValue)

      if (this.request) {
        this.searchParams = this.handleParams(params)

        // if (!this.searchParams) return false;
        let res = await this.request(this.handleParams(params))
        if (params.pageNo != 1) {
          if (res.data.list) {
            if (res.data.list.length == 0) {
              params.pageNo = params.pageNo - 1
              res = await this.request(this.handleParams(params))
            }
          }
        }
        this.souceData = this.handleSourceData(res)
        this.total = res.data.total
      }
    },

    // 刷新重置
    async resetTableData() {
      const params = {
        pageNo: 1,
        pageSize: 10,
        ...this.otherParams
      }

      this.reset = true
      this.searchData = {}
      this.pageNo = 1
      this.pageSize = 10
      if (this.request) {
        this.searchParams = this.handleParams(params)
        const res = await this.request(this.handleParams(params))
        this.souceData = this.handleSourceData(res)
        this.total = res.data.total
        this.reset = false
      }
    },
    // 批量导出 - 全局导出
    exportAllxlsx({
      api,
      filename,
      params = "",
      otherParams = "",
      type,
      suffix,
      isHeaderName = false
    }) {
      if (!params) {
        const initValue = this.initValue
        params = this.getParams(initValue)
        // delete params.pageSize;
        // delete params.pageNo;
      }

      api(params, otherParams)
        .then((blob) => {
          console.log(blob, "[[blob]]")
          // var contentDisposition = res.headers["content-disposition"];
          // var fileName = ""; // 从headers中获取后端返回文件名
          // if (isHeaderName && contentDisposition) {
          // 	contentDisposition = decodeURI(contentDisposition);
          // 	var patt = new RegExp("filename=([^;]+\\.[^\\.;]+);*");
          // 	var result = patt.exec(contentDisposition);
          // 	console.log(result[1], "result");
          // 	fileName = result[1].replace(/\"/g, "");
          // }

          // this.$fn.exportHelper({
          // 	file: res.data,
          // 	filename: filename || "导出文件",
          // 	type: type || "application/vnd.ms-excel",
          // 	suffix: suffix || ".xlsx",
          // });

          let downloadElement = document.createElement("a")
          let href = window.URL.createObjectURL(blob) // 创建下载的链接
          downloadElement.href = href
          if (filename) {
            if (filename.indexOf(suffix) > -1) {
              downloadElement.download = filename // 下载后文件名
            } else {
              downloadElement.download = filename + suffix // 下载后文件名
            }
          }
          document.body.appendChild(downloadElement)
          downloadElement.click() // 点击下载
          document.body.removeChild(downloadElement) // 下载完成移除元素
          window.URL.revokeObjectURL(href) // 释放掉blob对象
        })
        .catch((err) => {
          console.log(err, "err")
        })
    }
  }
}
</script>

<style lang="scss" scoped>
.app-template-page__footer {
  background: #ffffff;
  display: flex;
  padding: 14px 8px 20px 8px;
  justify-content: flex-end;
  font-size: 14px;
}

.app-warp {
  background: #ffffff;
  // padding-top: 10px;
  height: 100%;
  // overflow: auto;
  // display: flex;
  // flex-direction: column;
}
</style>

